package redis

import (
    "context"
    "fmt"
    "log"
    "time"

    mqtt "github.com/eclipse/paho.mqtt.golang"
    "github.com/go-redis/redis/v8"
)

var ctx = context.Background()

// Redis客户端初始化
func initRedis() *redis.Client {
    client := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379",
        Password: "", // 无密码的情况
        DB:       0,  // 使用默认数据库
    })

    // 测试连接
    _, err := client.Ping(ctx).Result()
    if err != nil {
        log.Fatalf("Redis连接失败: %v", err)
    }
    fmt.Println("Redis连接成功")
    return client
}

// 存储设备的订阅信息
func storeSubscription(client *redis.Client, deviceID, topic string) error {
    key := fmt.Sprintf("device:%s:subscriptions", deviceID)
    return client.SAdd(ctx, key, topic).Err() // 将topic添加到设备的订阅列表中
}

// 存储最近的数据包
func storeLastTenMessages(client *redis.Client, deviceID, message string) error {
    key := fmt.Sprintf("device:%s:recent_messages", deviceID)
    // 将消息添加到列表
    err := client.LPush(ctx, key, message).Err()
    if err != nil {
        return err
    }
    // 保留列表中的最新10条消息
    return client.LTrim(ctx, key, 0, 9).Err() // 保留最近10条数据
}

// 从Redis获取最近的10条数据
func getLastTenMessages(client *redis.Client, deviceID string) ([]string, error) {
    key := fmt.Sprintf("device:%s:recent_messages", deviceID)
    return client.LRange(ctx, key, 0, 9).Result()
}

func onMessageReceived(client mqtt.Client, msg mqtt.Message) {
    redisClient := initRedis()
    deviceID := "device123" // 假设设备ID
    topic := msg.Topic()
    payload := string(msg.Payload())

    // 存储订阅信息和消息
    storeSubscription(redisClient, deviceID, topic)
    storeLastTenMessages(redisClient, deviceID, payload)

    fmt.Printf("收到消息: %s\n", payload)
}

func main() {
    // MQTT客户端选项
    opts := mqtt.NewClientOptions().AddBroker("tcp://localhost:1883")
    opts.SetClientID("go-mqtt-client")
    opts.SetDefaultPublishHandler(onMessageReceived)

    // 创建并启动MQTT客户端
    client := mqtt.NewClient(opts)
    if token := client.Connect(); token.Wait() && token.Error() != nil {
        log.Fatalf("MQTT连接失败: %v", token.Error())
    }

    // 订阅设备的主题
    deviceID := "device123"
    topic := fmt.Sprintf("devices/%s/data", deviceID)
    token := client.Subscribe(topic, 0, nil)
    token.Wait()
    fmt.Printf("订阅主题: %s\n", topic)

    // 模拟运行，保持主程序执行
    time.Sleep(5 * time.Minute)
    client.Disconnect(250)
}